package com.ruoyi.function.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.UtilException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.demowechatpay.pojo.dto.WeChatTransferDTO;
import com.ruoyi.demowechatpay.pojo.vo.MyTransferCreateResult;
import com.ruoyi.demowechatpay.service.TransferService;
import com.ruoyi.function.constant.BusinessConstants;
import com.ruoyi.function.service.IUserFlowingService;
import com.ruoyi.message.controller.NoticeController;
import com.ruoyi.message.notice.vo.NoticeVO;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.function.mapper.TransferResultMapper;
import com.ruoyi.function.domain.TransferResult;
import com.ruoyi.function.service.ITransferResultService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 商户支付用户记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-03-27
 */
@Service
public class TransferResultServiceImpl implements ITransferResultService 
{

    @Value("${wx.appId}")
    public void setWxAppId(String appId) {
        Wx_APP_ID = appId;
    }

    @Value("${wx.appSecret}")
    public void setWxAppSecret(String appSecret) {
        Wx_APP_SECRET = appSecret;
    }
    private static String Wx_APP_ID;
    private static String Wx_APP_SECRET;


    @Autowired
    private TransferResultMapper transferResultMapper;
    @Autowired
    private TransferService transferService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IUserFlowingService userFlowingService;
    @Autowired
    private NoticeController noticeController;
    /**
     * 查询商户支付用户记录
     *
     * @param id 商户支付用户记录主键
     * @return 商户支付用户记录
     */
    @Override
    public TransferResult selectTransferResultById(Long id)
    {
        return transferResultMapper.selectTransferResultById(id);
    }

    /**
     * 查询商户支付用户记录列表
     *
     * @param transferResult 商户支付用户记录
     * @return 商户支付用户记录
     */
    @Override
    public List<TransferResult> selectTransferResultList(TransferResult transferResult)
    {
        return transferResultMapper.selectTransferResultList(transferResult);
    }

    /**
     * 新增商户支付用户记录
     *
     * @param transferResult 商户支付用户记录
     * @return 结果
     */
    @Override
    public int insertTransferResult(TransferResult transferResult)
    {
        transferResult.setCreateTime(DateUtils.getNowDate());
        return transferResultMapper.insertTransferResult(transferResult);
    }

    /**
     * 修改商户支付用户记录
     *
     * @param transferResult 商户支付用户记录
     * @return 结果
     */
    @Override
    public int updateTransferResult(TransferResult transferResult)
    {
        return transferResultMapper.updateTransferResult(transferResult);
    }

    /**
     * 批量删除商户支付用户记录
     *
     * @param ids 需要删除的商户支付用户记录主键
     * @return 结果
     */
    @Override
    public int deleteTransferResultByIds(Long[] ids)
    {
        return transferResultMapper.deleteTransferResultByIds(ids);
    }

    /**
     * 删除商户支付用户记录信息
     *
     * @param id 商户支付用户记录主键
     * @return 结果
     */
    @Override
    public int deleteTransferResultById(Long id)
    {
        return transferResultMapper.deleteTransferResultById(id);
    }

    /**
     * 微信支付
     * @param userId
     * @param balance
     * @param auditId
     * @param userTypes
     */
    @Override
    @Transactional
    public void weChatPaymentMake(Long userId, BigDecimal balance, Long auditId, String userTypes) {
        SysUser user = sysUserMapper.selectUserById(userId);
        if (StringUtils.isNull(user) || StringUtils.isNull(user.getOpenid())) {
            throw new UtilException("用户不存在或用户的openid不存在");
        }

        WeChatTransferDTO transferDTO = new WeChatTransferDTO();
        transferDTO.setAppId(Wx_APP_ID);
        transferDTO.setOpenid(user.getMerchantOpenid());
        transferDTO.setUserName(user.getRealName());
        transferDTO.setTransferAmount(convertYuanToFen(balance));
        transferDTO.setBatchRemark(String.valueOf(auditId));

        MyTransferCreateResult transferResult = transferService.transferBills(transferDTO);

        TransferResult result = new TransferResult();
        result.setTransferBillNo(transferResult.getTransferBillNo());
        result.setAppId(Wx_APP_ID);
        result.setAuditId(auditId);
        result.setState(transferResult.getState());
        result.setPackageInfo(transferResult.getPackageInfo());
        result.setBalance(balance);
        result.setUserType(userTypes);
        result.setCreateBy(String.valueOf(user.getUserId()));
        result.setCreateTime(DateUtils.getNowDate());
        result.setUserId(userId);

        int i = transferResultMapper.insertTransferResult(result);

    }

    @Override
    public int changeStatus(TransferResult transferResult) {
        TransferResult result = transferResultMapper.selectTransferResultById(transferResult.getId());
        transferResult.setIsFinished("1");
        NoticeVO noticeVO = new NoticeVO();
        noticeVO.setReceiverId(result.getUserId() + "");

        noticeVO.setUserType(result.getUserType());
        if (BusinessConstants.CANCELING.equals(transferResult.getState())){
            // 修改用户余额
            userFlowingService.addAmount(result.getUserId(), result.getBalance(), BusinessConstants.dict.fee_type_3, result.getUserType(), null);
            //发送消息
            noticeVO.setMessageContent( result.getBalance()+BusinessConstants.message_2);
        }else if (BusinessConstants.SUCCESS.equals(transferResult.getState())){
            noticeVO.setMessageContent(BusinessConstants.message_4);
        }
        noticeController.add(noticeVO);
        return transferResultMapper.updateTransferResult(transferResult);
    }

    /**
     * 将 BigDecimal 类型的金额（元）转换为分（long 类型）
     * @param yuan 金额（单位：元），必须非空且小数位数不超过 2 位
     * @return 分（单位：分）
     * @throws IllegalArgumentException 如果金额为 null 或小数位数超过 2 位
     */
    public static Integer convertYuanToFen(BigDecimal yuan) {
        // 1. 校验输入
        if (yuan == null) {
            throw new IllegalArgumentException("金额不能为 null");
        }

        // 校验小数位数不超过 2 位
        if (yuan.scale() > 2) {
            throw new IllegalArgumentException("金额小数位数不能超过 2 位");
        }

        // 2. 转换为分并四舍五入
        BigDecimal fen = yuan
                .multiply(new BigDecimal("100"))  // 元转分
                .setScale(0, RoundingMode.HALF_UP); // 四舍五入到整数

        // 3. 返回 long 类型
        try {
            return fen.intValueExact(); // 若超出 Integer 范围，抛出 ArithmeticException
        } catch (ArithmeticException e) {
            throw new ArithmeticException("金额超出 Integer 范围，请改用 Long 类型");
        }
    }
}
